鐵人賽 React javascript nodejs
鐵人賽第17天,週末假日,難得可以賴個床到八點半,但心裡掛念的還是今天的文章,不囉唆,立刻上工。![]()
input事件及reducer的動作,做個完整的結合。input.js中,新增一組state,同時觸發input 的 onChange事件,讓使用者輸入文字時,能即時更新到state之中,這樣,當我們按下send按鈕後,便可以直接從這個state取出輸入的文字,並進行ADD動作
msg: 暫存input欄位文字setMsg: 存放input文字的stateFunc
// input.js
import React, { useContext, useState } from "react";
import { ContextStore } from "./ToDoApp";
export default function Input() {
const [msg, setMsg] = useState("");
const { appReducer } = useContext(ContextStore);
const dispatch = appReducer[1];
console.log("msg", msg); //<--放一個console驗證看看
return (
<div>
<input
style={{ width: "150px" }}
onChange={(e) => setMsg(e.target.value)}
></input>
<button>{"Send"}</button>
</div>
);
}
Chrome inspector中的console來驗證看看,Wow...果然每輸入一個文字,都有顯示喔
Reducer,我們必須建立一個input 的 onClick事件,並在過程中完成:
- 包裝訊息為
object格式,如:{newEvent:msg}
// input.js
import React, { useContext, useState } from "react";
import { ContextStore } from "./ToDoApp";
// Step1: 建立一個handleAddClick事件,負責包裝訊息以符合reducer格式,並回傳dispatch完成新增訊息的動作,
function handleAddClick(newMsg, dispatch) {
const anEvent = { type: "ADD", newEvent: newMsg};
return (e)=>dispatch(anEvent); //<--為了讓handleAddClick func讓onClick使用,必須回傳一個func
}
// Step2: 我們在button新增一個onClick事件,並連結到建立一個handleAddClick事件
export default function Input() {
const [msg, setMsg] = useState("");
const { appReducer } = useContext(ContextStore);
const dispatch = appReducer[1];
console.log("msg", msg); //<--放一個console驗證看看
return (
<div>
<input
style={{ width: "150px" }}
onChange={(e) => setMsg(e.target.value)}
></input>
<button onClick={handleAddClick(msg, dispatch)}>{"Send"}</button>
</div>
);
}
toDoList之後,我們會先運用switch判讀action.type確定它的動作,再到相對case進行處理。return toDoList.push(action.newEvent),來看看會發生什麼事...// reducers/js
export default function reducers(toDoList, action) {
switch (action.type) {
case "ADD":
return toDoList.push(action.newEvent);
default:
return toDoList;
}
}

node來驗證一下。我們建立一個空的Array並利用push來新增一個文字Hello,你看看會回覆什麼訊息let result = [].push("hello")
console.log(result) // 1
Array.push會回傳當下Array的長度,故我們不能直接回傳。而且,這樣的寫法也犯了幾個錯:
React禁止我們直接修改state,故直接對reducer的state做修改,是行不通的。不過,我們可以用Array解構賦值的方式,複製一份toDoList並做修改。- 不要直接回傳
Array.push,應該分先push再回傳。
// reducers.js
export default function reducers(toDoList, action) {
let newToDoList = [...toDoList];
switch (action.type) {
case "ADD":
newToDoList.push(action.newEvent); //<-- 先push
break;
default:
console.log("toDoList", toDoList); //<--直接印出舊的
break;
}
return newToDoList; //<--不管動作如何,直接回傳複製過來的newToDoList
}
}

key上去import React, { useContext } from "react";
import { ContextStore } from "./ToDoApp";
export default function ToDoList() {
const { appReducer } = useContext(ContextStore);
const toDoList = appReducer[0];
const result = toDoList.map((e, idx) => (<p key={`cmd-${idx}`}>{e}</p>));
return result;
}

ToDoApp中的事件處理與reducer做完整的連結,讓事件可以順利的新增到toDoList之中。